package org.opencare.ndwc.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opencare.ndwc.messaging.EDXLBuilder;
import org.opencare.ndwc.model.DisasterType;
import org.opencare.ndwc.model.Event;
import org.opencare.ndwc.model.EventLevel;
import org.opencare.ndwc.model.EventType;
import org.opencare.ndwc.model.GlobalEvent;
import org.opencare.ndwc.persistence.DisasterTypeDao;
import org.opencare.ndwc.persistence.EventDao;
import org.opencare.ndwc.persistence.EventLevelDao;
import org.opencare.ndwc.persistence.EventTypeDao;
import org.opencare.ndwc.plugin.TopicPublisher;
import org.springframework.transaction.annotation.Transactional;

public class EventManagerImpl implements EventManager {

	private EventDao eventDao;
	private EventTypeDao eventTypeDao;
	private EventLevelDao eventLevelDao;
	private DisasterTypeDao disasterTypeDao;
	private TopicPublisher privatePublisher;
	private TopicPublisher publicPublisher;
	private String senderName = null;

	private EDXLBuilder edxlBuilder;

	protected final Log logger = LogFactory.getLog(getClass());

	/**
	 * 
	 */
	public EventManagerImpl() {
		// TODO Auto-generated constructor stub
	}

	public void setEdxlBuilder(EDXLBuilder edxlBuilder) {
		this.edxlBuilder = edxlBuilder;
	}

	public void setEventDao(EventDao eventDao) {
		this.eventDao = eventDao;
	}

	public void setEventTypeDao(EventTypeDao eventTypeDao) {
		this.eventTypeDao = eventTypeDao;
	}

	public void setEventLevelDao(EventLevelDao eventLevelDao) {
		this.eventLevelDao = eventLevelDao;
	}

	public void setDisasterTypeDao(DisasterTypeDao disasterTypeDao) {
		this.disasterTypeDao = disasterTypeDao;
	}

	public void setPrivatePublisher(TopicPublisher privatePublisher) {
		this.privatePublisher = privatePublisher;
	}

	public void setPublicPublisher(TopicPublisher publicPublisher) {
		this.publicPublisher = publicPublisher;
	}

	@Transactional
	@Override
	public Event addEvent(String topic, String description, Long eventTypeId,
			Long eventLevelId, Long disasterTypeId, String[] mapPath,
			String isPublic) {
		// TODO Auto-generated method stub

		EventType eventType = eventTypeDao.find(eventTypeId);
		EventLevel eventLevel = eventLevelDao.find(eventLevelId);
		DisasterType disasterType = disasterTypeDao.find(disasterTypeId);

		Event event = new Event();
		event.setTopic(topic);
		event.setDescription(description);

		if (mapPath.length > 0)
			event.setMapPath(mapPath[0]);
		event.setHasEventType(eventType);
		event.setHasLevel(eventLevel);
		event.setHasDisasterType(disasterType);
		eventDao.save(event);

		StringBuffer idBuff = new StringBuffer();
		idBuff.append(this.senderName).append("-");
		idBuff.append(disasterType.getType()).append("-");
		idBuff.append(event.getId().toString());

		String eventID = idBuff.toString();

		event.setIdentifier(eventID);

		try {

			if ((isPublic != null) && (isPublic.equalsIgnoreCase("on"))) {

				// put convert to edxl
				String edxlMessage = edxlBuilder.build(eventID, topic,
						description, eventType.getName(),
						eventLevel.getLevel(), disasterType.getType(), mapPath,
						true);

				logger.debug(edxlMessage);
				publicPublisher.publish(edxlMessage);
				privatePublisher.publish(edxlMessage);
			} else {
				// put convert to edxl
				String edxlMessage = edxlBuilder.build(eventID, topic,
						description, eventType.getName(),
						eventLevel.getLevel(), disasterType.getType(), mapPath,
						false);
				logger.debug(edxlMessage);
				privatePublisher.publish(edxlMessage);
			}

		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return event;
	}

	@Override
	public Event findEventById(Long id) {
		// TODO Auto-generated method stub
		return eventDao.find(id);
	}

	@Override
	public List<Event> findEventByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<DisasterType> findAllDisasterType() {
		// TODO Auto-generated method stub
		return disasterTypeDao.findAll();
	}

	@Override
	public Map<String, Object> findAllDisasterTypeMap() {
		// TODO Auto-generated method stub
		List<DisasterType> disasterTypeList = disasterTypeDao.findAll();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (DisasterType e : disasterTypeList) {
			Map<String, String> row;

			row = new HashMap<String, String>();
			row.put("id", e.getId().toString());
			row.put("type", e.getType());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", list.size());
		map.put("data", list);

		return map;
	}

	@Override
	public List<Event> findAllEvent() {
		// TODO Auto-generated method stub
		return eventDao.findAll();
	}

	@Override
	public Map<String, Object> findAllEventMap() {
		// TODO Auto-generated method stub

		List<Event> eventList = eventDao.findAll();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (Event e : eventList) {
			Map<String, String> row;

			row = new HashMap<String, String>();
			row.put("id", e.getId().toString());
			row.put("topic", e.getTopic());
			row.put("description", e.getDescription());
			row.put("eventType", e.getHasEventType().getName());
			row.put("level", e.getHasLevel().getLevel());
			row.put("disasterType", e.getHasDisasterType().getType());
			row.put("dateCreated", e.getDateCreated().toString());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", list.size());
		map.put("data", list);

		// String str = JSONSerializer.toJSON(map).toString();
		// System.out.println(str);
		return map;
	}

	@Override
	public Map<String, Object> findPagingEventMap(int start, int limit) {
		// TODO Auto-generated method stub
		List<Event> eventList = eventDao.findAll(start, limit);
		Long totSize = eventDao.countAllEvent();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (Event e : eventList) {
			Map<String, String> row;

			String dummy = e.getDescription().replace("\n", "<br/>");
			dummy = dummy.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

			row = new HashMap<String, String>();
			row.put("id", e.getIdentifier());
			row.put("topic", e.getTopic());
			row.put("description", dummy);
			row.put("mapPath", e.getMapPath());
			row.put("eventType", e.getHasEventType().getName());
			row.put("level", e.getHasLevel().getLevel());
			row.put("disasterType", e.getHasDisasterType().getType());
			row.put("dateCreated", e.getDateCreated().toString());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", totSize);
		map.put("data", list);

		// String str = JSONSerializer.toJSON(map).toString();
		logger.debug("totSize: " + totSize);
		return map;
	}

	@Override
	public Map<String, Object> findPagingGlobalEventMap(int start, int limit) {
		// TODO Auto-generated method stub
		List<GlobalEvent> eventList = eventDao.findAllGlobalEvent(start, limit);
		Long totSize = eventDao.countAllGlobalEvent();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (GlobalEvent e : eventList) {
			Map<String, String> row;

			String dummy = e.getDescription().replace("\n", "<br/>");
			dummy = dummy.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

			row = new HashMap<String, String>();
			row.put("id", e.getIdentifier());
			row.put("sender", e.getSender());
			row.put("topic", e.getHeadline());
			row.put("description", dummy);
			row.put("category", e.getCategory());
			row.put("event", e.getEvent());
			row.put("urgency", e.getUrgency());
			row.put("certainty", e.getCertainty());
			row.put("severity", e.getSeverity());
			row.put("language", e.getLanguage());
			row.put("mapPath", e.getMapPath());
			row.put("pubDate", e.getPubDate().toString());
			row.put("createdDate", e.getCreatedDate().toString());
			row.put("alertLevel", e.getAlertLevel());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", totSize);
		map.put("data", list);

		logger.debug(totSize);
		return map;
	}

	@Override
	public List<EventLevel> findAllEventLevel() {
		// TODO Auto-generated method stub
		return eventLevelDao.findAll();
	}

	@Override
	public Map<String, Object> findAllEventLevelMap() {
		// TODO Auto-generated method stub
		List<EventLevel> eventLevelList = eventLevelDao.findAll();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (EventLevel e : eventLevelList) {
			Map<String, String> row;

			row = new HashMap<String, String>();
			row.put("id", e.getId().toString());
			row.put("level", e.getLevel());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", list.size());
		map.put("data", list);

		return map;
	}

	@Override
	public List<EventType> findAllEventType() {
		// TODO Auto-generated method stub
		return eventTypeDao.findAll();
	}

	@Override
	public Map<String, Object> findAllEventTypeMap() {
		// TODO Auto-generated method stub
		List<EventType> eventTypeList = eventTypeDao.findAll();

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		for (EventType e : eventTypeList) {
			Map<String, String> row;

			row = new HashMap<String, String>();
			row.put("id", e.getId().toString());
			row.put("type", e.getName());

			list.add(row);
		}

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("totalSize", list.size());
		map.put("data", list);

		return map;
	}

	@Override
	public List<List<String>> getPossibleBusinessGroups(String userId,
			String query) {
		// TODO Auto-generated method stub
		List<List<String>> groupNames = new ArrayList<List<String>>();
		List<String> groupName;

		groupName = new ArrayList<String>();
		groupName.add("group1");
		groupNames.add(groupName);

		groupName = new ArrayList<String>();
		groupName.add("group2");
		groupNames.add(groupName);

		groupName = new ArrayList<String>();
		groupName.add("group3");
		groupNames.add(groupName);

		logger.debug(userId);
		logger.debug(query);

		return groupNames;
	}

	public void setSenderName(String senderName) {
		this.senderName = senderName;
	}

}
